//
//  SemaphoreViewController.m
//  Gunterapple
//
//  Created by 热带雨林 on 2020/7/11.
//  Copyright © 2020 热带雨林. All rights reserved.
//

#import "SemaphoreViewController.h"

@interface SemaphoreViewController ()
@property (nonatomic, assign) NSInteger ticketCount;

//创建私有信号量属性
@property (nonatomic, strong) dispatch_semaphore_t semaphoreLock;

@end

@implementation SemaphoreViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor redColor];
    
    [self semaphoreSale];
}
- (void)semaphoreSale{
    //初始化信号量 可以根据需求设置需要的信号总量
    //初始化之后信号量就是1  设置为0 就不执行了
    //同步锁！！！
    self.semaphoreLock = dispatch_semaphore_create(1);
    
    //票数
    self.ticketCount = 5;
    
    //两个窗口
    dispatch_queue_t queue1 = dispatch_queue_create("com.dianYaNetwork.www.Gunterapple", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_queue_t queue2 = dispatch_queue_create("com.dianYaNetwork.www.Gunterapple", DISPATCH_QUEUE_CONCURRENT);
    
    //异步买票
    dispatch_async(queue1, ^{
        //窗口1
        [self saleTicketSafe];
//        [self saleTickSy];
    });
    dispatch_async(queue2, ^{
       //窗口2
        [self saleTicketSafe];
//        [self saleTickSy];
    });
}
- (void)saleTickSy{
    /**
     2021-01-26 22:49:13.479419+0800 Gunterapple[13720:849796] 已买一张，剩余票数：4，窗口:<NSThread: 0x600000d2df40>{number = 7, name = (null)}
     2021-01-26 22:49:14.481835+0800 Gunterapple[13720:849796] 已买一张，剩余票数：3，窗口:<NSThread: 0x600000d2df40>{number = 7, name = (null)}
     2021-01-26 22:49:15.486727+0800 Gunterapple[13720:849796] 已买一张，剩余票数：2，窗口:<NSThread: 0x600000d2df40>{number = 7, name = (null)}
     2021-01-26 22:49:16.489825+0800 Gunterapple[13720:849796] 已买一张，剩余票数：1，窗口:<NSThread: 0x600000d2df40>{number = 7, name = (null)}
     2021-01-26 22:49:17.492936+0800 Gunterapple[13720:849796] 已买一张，剩余票数：0，窗口:<NSThread: 0x600000d2df40>{number = 7, name = (null)}
     */
    while (1) {
        @synchronized (self) {  //效果不是很好
            if(self.ticketCount > 0){
                self.ticketCount --;
                NSLog(@"已买一张，剩余票数：%ld，窗口:%@",(long)self.ticketCount,[NSThread currentThread]);
                
                //延时
                [NSThread sleepForTimeInterval:1];
            }else{
                NSLog(@"票已经卖完了！");
                NSLog(@"2");
                break;
            }
        }
    }
}

/*
 售票 安全
 **/
- (void)saleTicketSafe{
    //开始买票
    while (1) {
        /**
         //异步串行队列
         HH -- <NSThread: 0x600001e4b280>{number = 7, name = (null)}
         HH -- <NSThread: 0x600001e67b00>{number = 3, name = (null)}
         已买一张，剩余票数：4，窗口:<NSThread: 0x600001e4b280>{number = 7, name = (null)}
         1 -- <NSThread: 0x600001e4b280>{number = 7, name = (null)}
         已买一张，剩余票数：3，窗口:<NSThread: 0x600001e67b00>{number = 3, name = (null)}
         HH -- <NSThread: 0x600001e4b280>{number = 7, name = (null)}
         1 -- <NSThread: 0x600001e67b00>{number = 3, name = (null)}
         已买一张，剩余票数：2，窗口:<NSThread: 0x600001e4b280>{number = 7, name = (null)}
         HH -- <NSThread: 0x600001e67b00>{number = 3, name = (null)}
         1 -- <NSThread: 0x600001e4b280>{number = 7, name = (null)}
         已买一张，剩余票数：1，窗口:<NSThread: 0x600001e67b00>{number = 3, name = (null)}
         HH -- <NSThread: 0x600001e4b280>{number = 7, name = (null)}
         1 -- <NSThread: 0x600001e67b00>{number = 3, name = (null)}
         已买一张，剩余票数：0，窗口:<NSThread: 0x600001e4b280>{number = 7, name = (null)}
         HH -- <NSThread: 0x600001e67b00>{number = 3, name = (null)}
         票已经卖完了！
         1 -- <NSThread: 0x600001e4b280>{number = 7, name = (null)}
         2
         HH -- <NSThread: 0x600001e4b280>{number = 7, name = (null)}
         票已经卖完了！
         2
         */
        /**
         //异步并发队列
         //提示在展示说明展示科技
         HH -- <NSThread: 0x60000284c2c0>{number = 5, name = (null)}
         HH -- <NSThread: 0x60000289c200>{number = 6, name = (null)}
         已买一张，剩余票数：4，窗口:<NSThread: 0x60000284c2c0>{number = 5, name = (null)}
         1 -- <NSThread: 0x60000284c2c0>{number = 5, name = (null)}
         已买一张，剩余票数：3，窗口:<NSThread: 0x60000289c200>{number = 6, name = (null)}
         HH -- <NSThread: 0x60000284c2c0>{number = 5, name = (null)}
         1 -- <NSThread: 0x60000289c200>{number = 6, name = (null)}
         已买一张，剩余票数：2，窗口:<NSThread: 0x60000284c2c0>{number = 5, name = (null)}
         HH -- <NSThread: 0x60000289c200>{number = 6, name = (null)}
         已买一张，剩余票数：1，窗口:<NSThread: 0x60000289c200>{number = 6, name = (null)}
         1 -- <NSThread: 0x60000284c2c0>{number = 5, name = (null)}
         HH -- <NSThread: 0x60000284c2c0>{number = 5, name = (null)}
         1 -- <NSThread: 0x60000289c200>{number = 6, name = (null)}
         已买一张，剩余票数：0，窗口:<NSThread: 0x60000284c2c0>{number = 5, name = (null)}
         HH -- <NSThread: 0x60000289c200>{number = 6, name = (null)}
         票已经卖完了！
         1 -- <NSThread: 0x60000284c2c0>{number = 5, name = (null)}
         2
         HH -- <NSThread: 0x60000284c2c0>{number = 5, name = (null)}
         票已经卖完了！
         2
         */
        
        /**
            阻塞当前线程，造成线程死锁
         semaphore < 0 （即为-1）   阻塞当前线程进入等待状态 wait之后的代码就不执行了    信号量为0之后继续执行
         semaphore >= 0  正在阻塞的线程恢复继续执行  ？？
         */
        NSLog(@"HH -- %@",[NSThread currentThread]);
        //此处相当于加锁
//        NSLog(@"信号量总量:%@ , 线程: %@",self.semaphoreLock,[NSThread currentThread]);
        dispatch_semaphore_wait(self.semaphoreLock, DISPATCH_TIME_FOREVER);
        
        //
        if(self.ticketCount > 0){
            self.ticketCount --;
            NSLog(@"已买一张，剩余票数：%ld，窗口:%@",(long)self.ticketCount,[NSThread currentThread]);
            //延时
            [NSThread sleepForTimeInterval:1];
        }else{
            NSLog(@"票已经卖完了！");
            dispatch_semaphore_signal(self.semaphoreLock);
            NSLog(@"2");
            break;
        }
        //
        //相当于解锁
        dispatch_semaphore_signal(self.semaphoreLock);
        NSLog(@"1 -- %@",[NSThread currentThread]);
    }
}

@end
